package logica;

import java.util.ArrayList;
import java.util.LinkedList;

import logica.mensajes.MensajeDatos;

import patron_observer.Observador;
import patron_observer.Sujeto;
import red.SocketListener;

public class Centro_de_Mensajes implements Sujeto, SocketListener {
	private ArrayList<MensajeDatos>     nuevos;
	private ArrayList<MensajeDatos>     eliminados;
	private LinkedList<Observador> observadores_llegada_msj_nuevos; 
	private LinkedList<Observador> observadores_elimina_msj_nuevos;
	private LinkedList<Observador> observadores_llegada_msj_viejos;
	private LinkedList<Observador> observadores_borrado_msj_viejos;
	
	public Centro_de_Mensajes(){
		observadores_llegada_msj_nuevos = new LinkedList<Observador>();	
		observadores_elimina_msj_nuevos = new LinkedList<Observador>();
		observadores_llegada_msj_viejos = new LinkedList<Observador>();
		observadores_borrado_msj_viejos = new LinkedList<Observador>();
		
		nuevos 		 = new ArrayList<MensajeDatos>();
		eliminados 	 = new ArrayList<MensajeDatos>();	
	}
	
	// Va a ser llamado por los threads (clientes) de los sockets
	public synchronized void agregar_mensaje_nuevo(MensajeDatos x){
		nuevos.add(x);
		System.out.println(x.getElectro().cant_tomas());
		System.out.println(x.getElectro().da_toma(0).getColor());
		System.out.println(x.getElectro().da_toma(1).getColor());
		System.out.println(x.getElectro().da_toma(2).getColor());
		notif_llegada_de_nuevos_mensajes();
	}

	// Saca de la lista de nuevos
	private synchronized MensajeDatos quitar_mensaje(int i){
		MensajeDatos m = nuevos.get(i); 
		nuevos.remove(i);
		return m;
	}
	
	// Cambia de lista
	public synchronized void cambiar_de_lista(int i){
		MensajeDatos m = quitar_mensaje(i);
		notif_elimina_de_nuevos_mensajes(i);
		eliminados.add(m);
		notif_insercion_de_viejos_mensajes();
	}
	
	// Setea los datos del modelo de tabla (nuevos)
	public void setDatosNuevos(Modelo_de_Tabla modelo) {
		modelo.setDatos(nuevos);
	}
	
	// Setea los datos del modelo de tabla (viejos o "eliminados")
	public void setDatosViejos(Modelo_de_Tabla modelo) {
		modelo.setDatos(eliminados);
	}
	
	public MensajeDatos getMensajeNuevo(int i){
		return nuevos.get(i);
	}

	public MensajeDatos getMensajeViejo(int i){
		return eliminados.get(i);
	}
	
	/* Patron Observer - Sujeto */
		
	@Override
	public void sub_llegada_de_nuevos_mensajes(Observador o) {
		observadores_llegada_msj_nuevos.add(o);
	}

	@Override
	public void sub_elimina_de_nuevos_mensajes(Observador o) {
		observadores_elimina_msj_nuevos.add(o);
	}

	@Override
	public void sub_insercion_de_viejos_mensajes(Observador o) {
		observadores_llegada_msj_viejos.add(o);
	}

	@Override
	public void sub_elimina_de_viejos_mensajes(Observador o) {
		observadores_borrado_msj_viejos.add(o);
	}

	@Override
	public void notif_llegada_de_nuevos_mensajes() {
		for(Observador o: observadores_llegada_msj_nuevos){
			o.update_insercion();
		}
	}

	@Override
	public void notif_elimina_de_nuevos_mensajes(int i) {
		for(Observador o: observadores_llegada_msj_nuevos){
			o.update_quitar(i);
		}
	}

	@Override
	public void notif_insercion_de_viejos_mensajes() {
		for(Observador o: observadores_llegada_msj_nuevos){
			o.update_insercion();
		}
	}

	@Override
	public void notif_elimina_de_viejos_mensajes(int i) {
		for(Observador o: observadores_llegada_msj_nuevos){
			o.update_quitar(i);
		}
	}

	@Override
	public void agregar_mensaje(MensajeDatos m) {
		agregar_mensaje_nuevo(m);
	}

}
